/**
 * Diplomova prace
 * - nastaveni zakladnich parametru a ulozeni do profilu
 * - pokud probehne vse v poradku je odeslana SMS s textem a udejem o kvalite signalu
 * - pokud je problem, je odeslana SMS o nefuncknosti
 * - otevreni komunikace pres seriovy port
 * - odeslani potvrzujici zpravy pres seriovy port
 * - nacteni zpravy pres seriovy port a odeslani SMS
 * - testovano s PC - posilani retezcu pres hyperterminal (zatim nemam redukci k teplomeru, 
 *   ale princip stejny)
 * - impementace databaze RecordStore pro ukladani dat
 * - nacteni dat ze seriove linky, ulozeni zaznamu vcetne aktualniho datumu a casu
 *******************************************************************************************
 * - pridano:
 *                  - pin GPIO4 nastaven jako vyskoky vystup
 *                  - pripojena LED dionda, ktera signalizuje prijeti znaku bliknutim
 *
 */
package tcinert;

import com.siemens.icm.io.ATCommand;
import com.siemens.icm.io.ATCommandFailedException;
import com.siemens.icm.io.ATCommandResponseListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Calendar;
import java.util.Date;
import javax.microedition.io.CommConnection;
import javax.microedition.io.Connection;
import javax.microedition.io.Connector;
import javax.microedition.io.InputConnection;
import javax.microedition.io.OutputConnection;
import javax.microedition.midlet.MIDlet;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;

/**
 * @version 
 * @author Tomas Cinert
 */
public class BlikLED extends MIDlet
{
  ATCommand at;
  ATCommandResponseListener listener;
  String kvalita;
  InputStream input;
  int c;
  char temp;
  CommConnection spojeni;
  OutputStream output;
  RecordStore databaze;
  byte[] a;
  int index = 0;
  
  /**
  * Konstruktor 
   * - incializace promenne AT Command, osetreni vyjimek 
   * - vytvoreni databaze typu RecordStore - vyhoda teto databaze, ze data jsou uchovana 
   *   i po ukonceni MIDletu - permanentni pamet 
   * - pridan listener na odpoved na AT prikazy (zatim ne na URC, bude pridan dle potreby) 
   * - vytvoreni spojeni se seriovym portem, nastaveny parametry a odeslani potvrzovaci zpravy
   **/
  public BlikLED()
  {
    try
    {
      at = new ATCommand(false);
      databaze = RecordStore.openRecordStore("DB", true);      // Otvereni databaze se jmenem DB- pokud neexistuje dojde k vytvoreni (druhy parametr -true)
    } catch (RecordStoreException ex) {
      ex.printStackTrace();
    } catch (ATCommandFailedException ex) {
      ex.printStackTrace();
    } catch (IllegalStateException ex) {
      ex.printStackTrace();
    }
    listener = new ATCommandResponseListener()         // Listener na odezvu na ATprikazy
    {
      public void ATResponse(String Response) {
       // zapisCOM(Response);
        if (Response.startsWith("+CSQ", 2))
        {
           kvalita = Response;
        }

        if (Response.startsWith("ERROR", 2)) {
          
            destroyApp(true);
           notifyDestroyed();
        }
        else if (Response.startsWith("+CREG:", 2))
        {
          if (!Response.startsWith("+CREG: 0,1", 2)) {
            ATsend("AT+CMGS=\"+420604450956\"\r");
            ATsend("Konfigurace selhala: \032");
            destroyApp(true);
            notifyDestroyed();
          }
        }
      }
    };
    
    try
    { // Vytvoreni spojeni na portu COM0 s rychlosti 115200 pro Cteni/Zapis s povolenym timeoutem - pokud dojde k preteceni je generovana vyjimka
      spojeni = ((CommConnection)Connector.open("comm:COM0;baudrate=115200", 3, true));
      input = spojeni.openInputStream();
      output = spojeni.openOutputStream();
      String zprava = "Spojeni otevreno";
      zapisCOM(zprava);
    }
    catch (IOException ex) {
      destroyApp(true);
      notifyDestroyed();
    }
  }
  /**
   * Metoda na poslani AT prikazu
   * - po odeslani je vlakno uspano na 1 sekundu z duvodu cekani na vykonani prikazu,
   *  jelikoz je pouzita neblokujici varianta metody send
   */
  public void ATsend(String ATprikaz)
  {
    try
    {
      at.send(ATprikaz, listener);
      Thread.sleep(1000L);
    } catch (InterruptedException ex) {
      ex.printStackTrace();
    } catch (ATCommandFailedException ex) {
      ex.printStackTrace();
    } catch (IllegalStateException ex) {
      ex.printStackTrace();
    } catch (IllegalArgumentException ex) {
      ex.printStackTrace();
    }
  }
  /**
   * Metoda na zapis dat na seriovy port
   *@param zprava
   */
  public void zapisCOM(String zprava)
  {
    try
    {
      output.write(zprava.getBytes());
    }
    catch (IOException e)
    {
    }
  }
  /**
   * Metoda na zapis do databaze
   * - data jsou ulozena vcetne akutalniho data a casu 
   */
  public void zapisDB(String zaznam)
  {
    byte[] a = null;
    Date d = new Date();
    Calendar kalendar = Calendar.getInstance();
    kalendar.setTime(d);
    String cas = kalendar.get(5) + "." + kalendar.get(2) + "  " + kalendar.get(11) + ":" + kalendar.get(12);
    try {
      cas = cas + "   ;   " + zaznam;
      a = cas.getBytes();
      index = databaze.addRecord(a, 0, a.length);  // Vraci index, na ktery byl zaznam ulozen (zatim nevyuzito)
    }
    catch (RecordStoreException e)
    {
    }
  }
  /**
   * Spousteci metoda MIDletu 
   * - je volana po spusteni MIDletu 
   * - jsou cteny znaky ye serioveho portu a jsou ukladany do databaze, dokud neni prijata klavesa enter 
   * - v druhe casti se nastavuje GSM modul do potrebneho satvu a je odeslana inforamcni sms
   **/
  public void startApp()
  {
    byte[] uloz = null;
    ATsend("AT^SPIO=1\r");      // Otvereni GPIO pinu
      //ATsend("AT^SCPIN=1,3,1\r");
    while (temp != '\r') {
      try {
        ATsend("AT^SCPIN=0,3,1\r");     // Zavreni pinu 4
        c = input.read();
        ATsend("AT^SCPIN=1,3,1,1");     // "Otevreni" pinu - nastaveni jako vyskoy vystup
        
      } catch (Exception ex) {
        ex.printStackTrace();
      }
      temp = (char)c;
      zapisDB(String.valueOf(temp));
      zapisCOM(String.valueOf(temp));
            
    }

    try
    {
      for (int i = 1; i < databaze.getNumRecords(); i++)
      {
        uloz = databaze.getRecord(i);
        String msg = new String(uloz);
        zapisCOM(msg);
      }

    }
    catch (Exception e)
    {
    }
       
     
    destroyApp(true);
    notifyDestroyed();
  }

  public void pauseApp()
  {
  }
  /**
   * Metoda na zavreni databaze a serioveho spojeni
   */
  public void uzavreniSpojeni()
  {
    try
    {
       ATsend("AT^SCPIN=0,3,1,1\r");        // Uzavreni
       ATsend("AT^SPIO=0\r");
      databaze.closeRecordStore();
      input.close();
      output.close();
      spojeni.close();
    } catch (RecordStoreNotOpenException ex) {
      ex.printStackTrace();
    } catch (RecordStoreException ex) {
      ex.printStackTrace();
    }
    catch (IOException ex)
    {
      ex.printStackTrace();
    }
  }

  public void destroyApp(boolean unconditional) {
    zapisCOM("Koncime");        // Testovaci vypis
    uzavreniSpojeni();
  }
}